package com.tengju.bff.interfaces.covercharge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tengju.bff.interfaces.covercharge.constant.*;
import com.tengju.bff.interfaces.covercharge.entity.dto.WithdrawalApplyInfo;
import com.tengju.bff.interfaces.covercharge.entity.po.*;
import com.tengju.bff.interfaces.covercharge.enums.ProfitTypeEnum;
import com.tengju.bff.interfaces.covercharge.service.*;
import com.tengju.bff.interfaces.covercharge.service.message.client.UserMessageClient;
import com.tengju.bff.interfaces.covercharge.util.MoneyUtils;
import com.tengju.user.application.sms.SmsBizService;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.service.UserDocService;
import com.zoi7.component.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 提现申请记录相关
 *
 * @author fwy
 * @since 2020-02-24
 */
@Slf4j
@Service
public class AdminApplyRecordServiceImpl implements IAdminApplyRecordService {

    @Autowired
    @Lazy
    private LeTaxOneService leTaxOneService;

    @Autowired
    private IServiceLetaxWithdrawLogService serviceLetaxWithdrawLogService;

    @Autowired
    private IServiceFrozenDetailService serviceFrozenDetailService;

    @Autowired
    private IServiceWithdarwCycleAddService serviceWithdarwCycleAddService;

    @Autowired
    private IServiceSelfCertificationWithdrawService serviceSelfCertificationWithdrawService;

    @Autowired
    private IServiceInvoiceShippingLogService serviceInvoiceShippingLogService;

    @Autowired
    private IServiceAccountService serviceAccountService;

    @Autowired
    private SmsBizService smsBizService;

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private UserDocService userDocService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRegistrationStatus(Integer applyId, String remark, Integer status, String approvers) {
        if (StringUtils.isNotBlank(remark) && remark.length() > 200) {
            throw new ServiceException("审批说明不能超过200个字！");
        }
        ServiceLetaxWithdrawLog withdrawLog = serviceLetaxWithdrawLogService.getById(applyId);
        if (null == withdrawLog) {
            throw new ServiceException("该条审批记录不存在！");
        }
        if (LetaxWithdrawStatusEnum.CANCEL.getCode().equals(withdrawLog.getStatus())) {
            throw new ServiceException("该条审批记录已取消，无需审批！");
        }
        if (!LetaxWithdrawStatusEnum.APPLY.getCode().equals(withdrawLog.getStatus())) {
            throw new ServiceException("该条记录状态无需审批！");
        }

        //修改申请记录
        ServiceLetaxWithdrawLog updateLog = new ServiceLetaxWithdrawLog();
        updateLog.setRemark(remark);
        updateLog.setStatus(status);
        updateLog.setId(applyId);
        updateLog.setUpdatedAt(LocalDateTime.now());
        updateLog.setApprovers(approvers);
        updateLog.setCheckAt(LocalDateTime.now());
        serviceLetaxWithdrawLogService.updateById(updateLog);

        UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(withdrawLog.getIdCode()),null);

        //如果是拒绝，则为终态，解冻金额，减去周期表金额
        if (LetaxWithdrawStatusEnum.REJECT.getCode().equals(status)) {
            //查询冻结记录
            QueryWrapper<ServiceFrozenDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("biz_id", withdrawLog.getId());
            queryWrapper.eq("biz_code", ProfitTypeEnum.ls_withdraw);
            ServiceFrozenDetail frozenDetail = serviceFrozenDetailService.getOne(queryWrapper);
            if (frozenDetail == null) {
                throw new ServiceException("找不到该申请冻结金额记录！");
            }
            if (CoverChargeEnum.FreezeStatus.UN_FREEZE.getCode().equals(frozenDetail.getStatus())) {
                throw new ServiceException("该申请冻结金额已解冻,请确认！");
            }
            //冻结金额解冻
            ServiceFrozenDetail updateFrozen = new ServiceFrozenDetail();
            updateFrozen.setId(frozenDetail.getId());
            updateFrozen.setStatus(CoverChargeEnum.FreezeStatus.UN_FREEZE.getCode());
            updateFrozen.setUpdatedBy(approvers);
            updateFrozen.setUpdatedTime(LocalDateTime.now());

            //周期表金额修改
            ServiceWithdarwCycleAdd cycleAdd = serviceWithdarwCycleAddService.getById(withdrawLog.getCycleAddId());
            if (cycleAdd == null) {
                throw new ServiceException("找不到该申请对应的提现周期表！");
            }
            ServiceWithdarwCycleAdd updateAdd = new ServiceWithdarwCycleAdd();
            updateAdd.setId(cycleAdd.getId());
            BigDecimal total = cycleAdd.getTotal().subtract(withdrawLog.getMoney());
            updateAdd.setTotal(total);
            updateAdd.setRatio(MoneyUtils.sumRatio(total));
            updateAdd.setUpdatedAt(new Date());

            Integer accountType;
            if (CoverChargeEnum.ServiceAccountType.MANAGE_TYPE.getPlatform().equals(withdrawLog.getPlatformCode())) {
                accountType = CoverChargeEnum.ServiceAccountType.MANAGE_TYPE.getCode();
            } else {
                throw new ServiceException("账户类型不正确");
            }

            List<WithdrawalApplyInfo> infoList = new ArrayList<>();
            WithdrawalApplyInfo info = new WithdrawalApplyInfo();
            info.setBizId(withdrawLog.getId());
            info.setApplyMoney(withdrawLog.getMoney());
            infoList.add(info);

            serviceAccountService.unFreezeBalance(accountType, withdrawLog.getIdCode(), ProfitTypeEnum.ls_withdraw, withdrawLog.getMoney(), infoList);
            serviceWithdarwCycleAddService.updateById(updateAdd);

            Date nowDate = new Date();
            if (SignIdentityEnum.regist_soho.toString().equals(withdrawLog.getAuthType())) {
                leTaxOneService.updateOthersCycleAdd(nowDate, withdrawLog.getIdCode(), withdrawLog.getAccountId(), withdrawLog.getMoney());
            }

            serviceFrozenDetailService.updateById(updateFrozen);
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(withdrawLog.getPlatformCode())) {
//                //如果拒绝异步发送短信以及站内信
////                userMessageClient.sendDtServiceFeeMessage(withdrawLog.getIdCode(), "服务费申请通知",
////                        "您的一笔服务费申请被审核拒绝，请前往申请记录查看详情。", true, true, false);
//            }

            smsBizService.sendApplyVerifyReject(userInfo.getMobile());

            //userMessageClient.sendMobileMessage(withdrawLog.getIdCode(), "您的一笔服务费申请被审核拒绝，请前往申请记录查看详情。");

        } else if (LetaxWithdrawStatusEnum.PASS.getCode().equals(status)) {
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(withdrawLog.getPlatformCode())) {
//                //成功，直接发送站内信，push
////                userMessageClient.sendDtServiceFeeMessage(withdrawLog.getIdCode(), "服务费申请通知",
////                        "您的一笔服务费申请已审核通过，将于近日完成发放，请前往申请记录查看详情。", true, true, true);
//            }


        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSelfStatus(String remark, Integer applyId, Integer status, String approvers, String shippingNo, String expressName) {
        if (StringUtils.isNotBlank(remark) && remark.length() > 37) {
            throw new ServiceException("审批说明不能超过37个字！");
        }

        ServiceSelfCertificationWithdraw draw = serviceSelfCertificationWithdrawService.getById(applyId);
        if (null == draw) {
            throw new ServiceException("该条审批记录不存在！");
        }

        if (SelfWithdrawStatusEnum.CANCEL.getCode().equals(draw.getStatus())) {
            throw new ServiceException("该条审批记录已取消，无需审批！");
        }


        ServiceSelfCertificationWithdraw updatedraw = new ServiceSelfCertificationWithdraw();
        updatedraw.setRemark(remark);
        updatedraw.setStatus(status);
        updatedraw.setUpdatedAt(LocalDateTime.now());
        if (SelfWithdrawStatusEnum.FPASS.getCode().equals(status) || SelfWithdrawStatusEnum.FREJECT.getCode().equals(status)) {
            updatedraw.setCheckAt(LocalDateTime.now());
        }
        if (SelfWithdrawStatusEnum.SREJECT.getCode().equals(status) || SelfWithdrawStatusEnum.SPASS.getCode().equals(status)) {
            updatedraw.setRecheckt(LocalDateTime.now());
        }
        updatedraw.setId(applyId);
        updatedraw.setApprovers(approvers);

        UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(draw.getIdCode()),null);

        //判断是否是复审拒绝
        if (SelfWithdrawStatusEnum.SREJECT.getCode().equals(status)) {
            if (org.apache.commons.lang3.StringUtils.isBlank(shippingNo)) {
                throw new ServiceException("寄回快递单号不能为空");
            }
            if (StringUtils.isBlank(expressName)) {
                throw new ServiceException("寄回快递公司不能为空");
            }
            ServiceInvoiceShippingLog shippingLog = new ServiceInvoiceShippingLog();
            shippingLog.setExpressName(expressName);
            shippingLog.setShippingNo(shippingNo);
            shippingLog.setSelfWithdrawId(applyId);
            shippingLog.setImgId("");
            shippingLog.setType(2);
            //查询是否已经存在提现发票信息
            QueryWrapper<ServiceInvoiceShippingLog> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("self_withdraw_id", applyId);
            queryWrapper.eq("type", 2);
            ServiceInvoiceShippingLog checklog = serviceInvoiceShippingLogService.getOne(queryWrapper);
            if (checklog != null) {
                shippingLog.setId(checklog.getId());
            }
            serviceInvoiceShippingLogService.saveOrUpdate(shippingLog);
        }
        //如果最后是发放状态，修改账户冻结金额相关信息
        if (SelfWithdrawStatusEnum.SUCCESS.getCode().equals(status)) {

            //增加发放时间
            updatedraw.setPaymentTime(LocalDateTime.now());
            //查询冻结记录
            QueryWrapper<ServiceFrozenDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("biz_id", draw.getId());
            queryWrapper.eq("biz_code", ProfitTypeEnum.self_withdraw);
            ServiceFrozenDetail frozenDetail = serviceFrozenDetailService.getOne(queryWrapper);
            if (frozenDetail == null) {
                throw new ServiceException("找不到该申请冻结金额记录！");
            }
            if (CoverChargeEnum.FreezeStatus.UN_FREEZE.getCode().equals(frozenDetail.getStatus())) {
                throw new ServiceException("该申请冻结金额已解冻,请确认！");
            }
            //冻结金额解冻
            ServiceFrozenDetail updateFrozen = new ServiceFrozenDetail();
            updateFrozen.setId(frozenDetail.getId());
            updateFrozen.setStatus(CoverChargeEnum.FreezeStatus.UN_FREEZE.getCode());
            updateFrozen.setUpdatedBy(approvers);
            updateFrozen.setUpdatedTime(LocalDateTime.now());

            //修改账户金额
            serviceAccountService.updateBalanceForSuccess(draw.getAccountId(), draw.getMoney(), ProfitTypeEnum.self_withdraw, draw.getId(), null);
            serviceFrozenDetailService.updateById(updateFrozen);
        }
        serviceSelfCertificationWithdrawService.updateById(updatedraw);

        //发送短信或者站内信

        if (SelfWithdrawStatusEnum.FPASS.getCode().equals(status)) {
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(draw.getPlatformCode())) {
//                //初审通过,发送站内信以及短信
////                userMessageClient.sendDtServiceFeeMessage(draw.getIdCode(), "服务费申请通知",
////                        "您的服务费申请已通过初审，请及时邮寄发票并在申请记录中提交邮寄信息。", true, true, false);
//            }

            smsBizService.sendChargeEarlyPass(userInfo.getMobile());
            //userMessageClient.sendMobileMessage(draw.getIdCode(), "您的服务费申请已通过初审，请及时邮寄发票并在申请记录中提交邮寄信息。");
        } else if (SelfWithdrawStatusEnum.FREJECT.getCode().equals(status)) {
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(draw.getPlatformCode())) {
//                //初审拒绝,发送站内信以及短信
////                userMessageClient.sendDtServiceFeeMessage(draw.getIdCode(), "服务费申请通知",
////                        "您的服务费申请未通过初审，请前往申请记录查看详情重新提交。", true, true, false);
//            }
            smsBizService.sendChargeEarlyReject(userInfo.getMobile());
            //userMessageClient.sendMobileMessage(draw.getIdCode(), "您的服务费申请未通过初审，请前往申请记录查看详情重新提交。");
        } else if (SelfWithdrawStatusEnum.SPASS.getCode().equals(status)) {
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(draw.getPlatformCode())) {
//                //复审通过,发送站内信以及push
////                userMessageClient.sendDtServiceFeeMessage(draw.getIdCode(), "服务费申请通知",
////                        "您的服务费申请已通过复核，预计在2~3个工作日内发放至您尾号为【" + draw.getBankNo().substring(draw.getBankNo().length() - 4) + "】的银行卡，请注意查收。", true, true, true);
//            }

        } else if (SelfWithdrawStatusEnum.SREJECT.getCode().equals(status)) {
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(draw.getPlatformCode())) {
//                //复审拒绝,发送站内信以及短信
////                userMessageClient.sendDtServiceFeeMessage(draw.getIdCode(), "服务费申请通知",
////                        "您的服务费申请未通过复核，发票已通过到付件寄回，请前往申请记录查看详情重新邮寄。", true, true, false);
//            }

            smsBizService.sendChargeRecheckReject(userInfo.getMobile());
            //userMessageClient.sendMobileMessage(draw.getIdCode(), "您的服务费申请未通过复核，发票已通过到付件寄回，请前往申请记录查看详情重新邮寄。");
        } else if (SelfWithdrawStatusEnum.SUCCESS.getCode().equals(status)) {

            //发送短信
//            String messageContent = "亲爱的ABMer，";
//            Integer templateId = MessageTemplateIdEnum.ABM.getCode();//默认ABM

//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(draw.getPlatformCode())) {
//                //发放成功,发送站内信以及短信
////                userMessageClient.sendDtServiceFeeMessage(draw.getIdCode(), "服务费发放通知",
////                        "您的服务费申请已发放至尾号为【" + draw.getBankNo().substring(draw.getBankNo().length() - 4) + "】的银行卡，请注意查收。", true, true, false);
//
//            } else {
//                messageContent = "亲爱的服务商，";
//                templateId = MessageTemplateIdEnum.DT.getCode();
//            }
//
//            messageContent += "您本月的服务费申请已发放至尾号【" + draw.getBankNo().substring(draw.getBankNo().length() - 4) + "】银行卡，请注意查收。如有其他疑问，请在线咨询ABM客服。";

            smsBizService.sendChargeDistributeSuccess(userInfo.getMobile(),draw.getBankNo().substring(draw.getBankNo().length() - 4));
            //userMessageClient.sendMobileMessageByTemplate(draw.getIdCode(), templateId, messageContent);
        }

    }
}
